import { decompressFromBase64 } from "./libs/decompressFromBase64";

export interface DataItem {
    code: string;
    name: string;
    province: string;
    city: string;
    area: string;
    town: string;
    children?: DataItem[];
}

export interface Country {
    id: number;
    cnname: string;
    name: string;
    fullname: string;
    alpha2: string;
    alpha3: string;
    numeric: number;
}

declare type MinData =
    | string
    | {
        [ket: string]: MinData[];
    };

export function decompressString(compressed: string) {
    return decompressFromBase64(compressed) || "";
}

function decodeString(str: string) {
    const str0 = decompressString(str);
    if (str0.includes(";")) {
        return {
            isCountry: true,
            content: str0
                .replace(/([^,[\]{}:]+)/g, '"$1"')
                .replace(/\$L/g, "[")
                .replace(/\$R/g, "]")
                .replace(/\$l/g, "{")
                .replace(/\$r/g, "}"),
            hasChildren: false,
        };
    }
    return {
        isCountry: false,
        content: str0
            .replace(/([^,[\]{}:]+)/g, '"$1"')
            .replace(/\$L/g, "[")
            .replace(/\$R/g, "]")
            .replace(/\$l/g, "{")
            .replace(/\$r/g, "}")
            .replace(/G/g, "县")
            .replace(/H/g, "乡")
            .replace(/I/g, "镇")
            .replace(/J/g, "省")
            .replace(/K/g, "市")
            .replace(/L/g, "区")
            .replace(/A/g, "自治区")
            .replace(/B/g, "开发区")
            .replace(/C/g, "特别行政区")
            .replace(/D/g, "市辖区")
            .replace(/E/g, "自治")
            .replace(/F/g, "街道"),
        hasChildren: str0.includes("{"),
    };
}

export function decodeJson(str: string | [string]) {
    const s = decodeString(Array.isArray(str) ? str[0] : JSON.parse(str)[0]);
    const data = JSON.parse(s.content);
    if (s.isCountry) {
        return {
            country: data.map((item: string) => {
                const [id, cnname, name, fullname, alpha2, alpha3, numeric] = item.split(";").map((item) => item || "");
                return {
                    id: Number(id || "0"),
                    cnname,
                    name,
                    fullname,
                    alpha2,
                    alpha3,
                    numeric: Number(numeric || "0"),
                };
            }) as Country[],
            data: [] as DataItem[],
        };
    } else {
        const _decode = (list: MinData[]) => {
            return list.map((item): DataItem => {
                if (typeof item === "string") {
                    const [key, province, city, area, town] = item.split("|");
                    const [code, name] = key.replace(/^(\d+)/, "$1,").split(",");
                    return {
                        code,
                        name,
                        province,
                        city,
                        area,
                        town,
                        children: s.hasChildren ? [] : undefined,
                    };
                } else {
                    const item0 = Object.keys(item)[0];
                    const [key, province, city, area, town] = item0.split("|");
                    const [code, name] = key.replace(/^(\d+)/, "$1,").split(",");
                    return {
                        code,
                        name,
                        province,
                        city,
                        area,
                        town,
                        children: s.hasChildren ? (item[item0] ? _decode(item[item0]) : []) : undefined,
                    };
                }
            });
        };

        return {
            country: [] as Country[],
            data: _decode(data),
        };
    }
}
